package server

import (
	"awesomeProject1/push/plugin"
	"awesomeProject1/push/plugin/email"
	"awesomeProject1/push/plugin/im"
	"awesomeProject1/push/plugin/sms"
	"awesomeProject1/push/plugin/wechat"
	"log"
	"sync"
)

// PushService 消息推送服务
type PushService struct {
	pluginManager *plugin.PluginManager
}

// NewPushService 创建一个新的 PushService 实例
func NewPushService(pluginManager *plugin.PluginManager) *PushService {
	return &PushService{
		pluginManager: pluginManager,
	}
}

func Push(msgBean plugin.MsgRes) {

	// TODO 问题1：对各种渠道的发送，做管理（启用/禁用）
	// TODO 问题2：每种渠道(短信，邮件），独立子协成去处理
	// 1 初始化插件管理器
	pluginManager := InitPlugin()

	// 2.创建消息推送服务
	pushService := NewPushService(pluginManager)

	// 3.推送信息
	pushService.StartPush(msgBean)
}

// StartPush 异步处理消息推送
var wg sync.WaitGroup

func (ps *PushService) StartPush(msgBean plugin.MsgRes) {
	// 遍历所有插件，判断是否启用，如果启用则异步处理消息
	for name, plugin := range ps.pluginManager.Plugins {
		if plugin.IsEnabled() {
			log.Println("插件是否开启=================>", name, plugin.IsEnabled())
			vo := ps.getVo(msgBean, name) // TODO 不同插件需要的发送信息对象配置是不同的
			log.Println("==========================vo>", vo)
			wg.Add(1)                 // 等待组任务+1
			ps.remotePush(vo, plugin) // TODO 协程处理推送信息
		}
	}
	// 等待所有的推送协程完成再执行主协程结束
	wg.Wait()
	log.Println("==========================>推送完成")
}

func (ps *PushService) remotePush(vo plugin.MessageInfo, p plugin.Plugin) {
	log.Println("==========================>进入远程推送信息")
	log.Println("==========================>当前插件")
	defer func() {
		if err := recover(); err != nil {
			//TODO 底层代码有异常，在这里捕捉
			log.Println("=========================>捕获到异常", err)
		}
	}()
	defer wg.Done() //等待组任务完成 -1
	p.SendMessage(vo)
}

func (ps *PushService) getVo(msgBean plugin.MsgRes, name string) plugin.MessageInfo {
	switch name {
	case "sms":
		return plugin.MessageInfo{
			Receiver: msgBean.Phones,
			Message:  msgBean.Content,
		}
	case "im":
		return plugin.MessageInfo{
			Receiver: msgBean.WsIds,
			Message:  msgBean.Content,
		}
	case "email":
		return plugin.MessageInfo{
			Receiver: msgBean.Emails,
			Message:  msgBean.Content,
		}
	case "wechat":
		return plugin.MessageInfo{
			Receiver: msgBean.Wechats,
			Message:  msgBean.Content,
		}
	}
	return plugin.MessageInfo{
		Receiver: nil,
		Message:  "",
	}
}

// TODO 初始化信息插件管理器
func InitPlugin() *plugin.PluginManager {
	log.Println("==========================>初始化插件管理器")

	// TODO 这里应该从配置文件中获取
	channel := plugin.MsgChannel{
		Sms:    true,
		Email:  true,
		Im:     true,
		Wechat: false,
	}
	log.Println("==========================>读取配置文件查看开启插件")

	// 创建插件管理器
	pm := plugin.NewPluginManager()

	// 注册 并启用短信插件
	if channel.Sms == true {
		log.Println("==========================>开启短信插件")
		smsPlugin := &sms.SmsPlugin{}
		pm.RegisterPlugin("sms", smsPlugin)
		pm.EnablePlugin("sms")
		log.Println(smsPlugin)
	}

	// 注册 并启用邮箱插件
	if channel.Email == true {
		log.Println("==========================>开启邮箱插件")
		emailPlugin := &email.EmailPlugin{}
		pm.RegisterPlugin("email", emailPlugin)
		pm.EnablePlugin("email")
		log.Println(emailPlugin)
	}

	// 注册 并启用IM插件
	if channel.Im == true {
		log.Println("==========================>开启im插件")
		imPlugin := &im.ImPlugin{}
		pm.RegisterPlugin("im", imPlugin)
		pm.EnablePlugin("im")
		log.Println(imPlugin)
	}

	// 注册 并启用Wechat插件
	if channel.Wechat == true {
		log.Println("==========================>开启微信插件")
		wechatPlugin := &wechat.WechatPlugin{}
		pm.RegisterPlugin("wechat", wechatPlugin)
		pm.EnablePlugin("wechat")
		log.Println(wechatPlugin)
	}

	return pm
}
